home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Steal This CD
/
steal_this_cd.iso
/
Chapter 07 - Where the Hackers Are
/
virc200.exe
/
{app}
/
vircole.txt
< prev
next >
Wrap
Text File
|
2003-08-30
|
16KB
|
345 lines
Visual IRC 2.0 Automation Interface
Jesse McGrew
August 30, 2003
Interface primer
================
The COM standard defines a way to access objects by their interfaces. An
interface is basically a list of the object's capabilities (properties and
methods). Objects can support several interfaces at once, and if a program
has a pointer to one of an object's interfaces, it can query the object to
see if it supports another interface that the program wants to use.
An interface defines how you can interact with an object, but not how the
object works internally. Different programs can use different languages to
create objects, but if they all implement the same interface, they can be
used exactly the same way.
There are various ways of getting a pointer to one of the interfaces supplied
by an object. Once a pointer is retrieved, a compiled programs can access the
interface methods directly, as long as a type library is available when the
program is written.
However, when the description of the interface isn't available at compile
time, or if the program is written in an uncompiled language (e.g. a ViRC
script), there's another way to access the interface methods. OLE Automation
defines an interface called IDispatch, which is used to access methods and
properties by name. Most interfaces that applications expose to the public are
'dual interfaces', meaning they can be accessed directly and also through
IDispatch.
Using OLE Automation interfaces from ViRC scripts
=================================================
OVS handles can now refer to OLE Automation interfaces (IDispatch) obtained
from other programs, as well as objects from the VCL and user-defined classes.
The predefined handle "1" can be used to refer to ViRC's IVisualIRC interface
(see below), similar to how "0" can be used to refer to ViRC's main window.
OVS handles that refer to OLE Automation interfaces work almost just like other
handles. The differences are:
1. To create a handle referring to an Automation object, use $NewCOMObject()
instead of $New(). This function takes a CLSID surrounded by curly brackets.
For example, to create a new ViRC controller object that implements the
IVisualIRC interface, use:
$NewCOMObject({5F0D2E3B-66D5-4E11-B9D2-1756A53D4EDB}).
The return value is an object handle, or -1 if the class doesn't exist or
doesn't support IDispatch.
2. $ClassOf() always returns "IDispatch" when used with an OLE handle.
$ParentClassOf() always returns "IUnknown".
3. Properties of properties (or methods of properties) cannot be accessed
directly, as in $obj.Prop.Method. You must map the property, then call the
method with the new handle.
4. When calling a method through an Automation handle, each parameter is
treated as a list item:
$obj.Method param1 param2 $ListQuote(param3 contains spaces)
5. Indexed properties can be used with $Prop(), $MapProp(), and @P by giving
the index parameters in square brackets after the property name. Put a
space before the brackets so ViRC doesn't parse it as an array reference.
Just like in a method call, each index must be quoted as a list item when
appropriate: $Prop($obj.IndexedProp [index1 "index 2 contains spaces"])
6. Destroy, SafeDestroy, and UnmapObject all have the same effect on
Automation handles. The object won't actually be destroyed until all of
its interface pointers are released, including any pointers held by other
programs.
Other programs can map their own Automation objects into ViRC by calling
the IVisualIRC::MapInterface method. Here's an example in Delphi:
const
CLSID_VisualIRC: TGUID = '{5F0D2E3B-66D5-4E11-B9D2-1756A53D4EDB}';
LocalContext = CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER;
var
MyObject: IMyInterface; // must be a dual interface
VisualIRC: IVisualIRC;
Handle: Integer;
begin
// create your object and get its interface pointer
MyObject := TMyObject.Create as IMyInterface;
// get an IVisualIRC pointer
OleCheck(CoCreateInstance(CLSID_VisualIRC, nil, LocalContext,
IDispatch, VisualIRC));
// map the interface pointer to a handle
Handle := VisualIRC.MapInterface(MyObject as IDispatch);
end;
Exposing objects from ViRC scripts to other programs
====================================================
Interfaces exposed by ViRC
==========================
Better documentation may be provided later. For now, here is a listing of the
dispatch interfaces implemented by ViRC. Note that an IVisualIRC interface is
provided to all Language..EndLanguage blocks under the name 'VisualIRC', an
IVSSprout is provided under the names 'ViRCScript' and 'Versus', and an
interface to the current window is provided under the name 'Current' (the
interface is an IServer, IQuery, IChannel, IDCCChat, or IWhiteboard).
The 'Form' property returns an IDispatch interface that can be used to access
the properties of VCL objects. For example, this alias using VBScript will
change the caption of the window it is executed from:
Alias SETCAPTION
Language VBScript
Current.Form.Caption = Versus.GetVar("$1-")
EndLanguage
EndAlias
Child controls can be used as properties as well:
Alias DISABLETRAY
Language VBScript
' properties of "VisualIRC" can be used as global names (e.g. MainForm)
MainForm.TrayIcon.Active = False
EndLanguage
EndAlias
VCL objects can only be used through their IDispatch interfaces; all other
ViRC objects implement dual interfaces so they can use vtable binding with the
type library from ViRC.exe. Each vtable interface has the same GUID as its
respective dispatch interface.
The GetInterface method of IVSSprout can be used to retrieve an IDispatch
interface for an OVS object, given the object's handle. VCL classes and
user-defined classes can be accessed this way. For example:
Language VBScript
Set foo = VisualIRC.GlobalInterpreter.GetInterface(0)
foo.Caption = "Here is a new main form caption"
EndLanguage
Other applications can obtain an IVisualIRC interface through the CoClass with
CLSID = {5F0D2E3B-66D5-4E11-B9D2-1756A53D4EDB}.
Implemented dispatch interfaces:
IVisualIRC = dispinterface
['{A2F519D5-32EB-484A-BC70-CA25F4DB7080}']
property Version: Integer readonly dispid 2;
property MainForm: IDispatch readonly dispid 3;
property GlobalInterpreter: IVSSprout readonly dispid 4;
property ServerCount: Integer readonly dispid 6;
property Servers[Index: Integer]: IServer readonly dispid 7;
property DCCChatCount: Integer readonly dispid 8;
property DCCChats[Index: Integer]: IDCCChat readonly dispid 9;
function NewServer(const ServerName: WideString): IServer; dispid 10;
end;
IChildForm = dispinterface
['{B14CAFEE-6E91-42FF-9D15-3937D03D3923}']
property Kind: WindowKind readonly dispid 1;
property ID: Integer readonly dispid 2;
property Owner: IChildForm readonly dispid 3;
procedure Close; dispid 4;
property WindowName: WideString readonly dispid 5;
property Form: IDispatch readonly dispid 6;
end;
IOutputForm = dispinterface // inherits from IChildForm
['{CC885F1F-A1FC-46B8-A722-42E1832201F8}']
procedure Clear(ClearHistory: WordBool); dispid 8;
property History: IStrings readonly dispid 9;
procedure RunCommand(const Command: WideString); dispid 10;
property Output: ITextScroller readonly dispid 11;
property Kind: WindowKind readonly dispid 1;
property ID: Integer readonly dispid 2;
property Owner: IChildForm readonly dispid 3;
procedure Close; dispid 4;
property WindowName: WideString readonly dispid 5;
property Form: IDispatch readonly dispid 6;
end;
IQuery = dispinterface // inherits from IOutputForm
['{D80D1784-BD7D-46EC-A11D-0D15FB0AB4A1}']
property Nick: WideString readonly dispid 16;
procedure Clear(ClearHistory: WordBool); dispid 8;
property History: IStrings readonly dispid 9;
procedure RunCommand(const Command: WideString); dispid 10;
property Output: ITextScroller readonly dispid 11;
property Kind: WindowKind readonly dispid 1;
property ID: Integer readonly dispid 2;
property Owner: IChildForm readonly dispid 3;
procedure Close; dispid 4;
property WindowName: WideString readonly dispid 5;
property Form: IDispatch readonly dispid 6;
end;
IDCCChat = dispinterface // inherits from IOutputForm
['{A94DC4FF-19E6-470B-B85A-B60987D19A5F}']
property Nick: WideString readonly dispid 16;
property Session: IDCCSession readonly dispid 17;
procedure Clear(ClearHistory: WordBool); dispid 8;
property History: IStrings readonly dispid 9;
procedure RunCommand(const Command: WideString); dispid 10;
property Output: ITextScroller readonly dispid 11;
property Kind: WindowKind readonly dispid 1;
property ID: Integer readonly dispid 2;
property Owner: IChildForm readonly dispid 3;
procedure Close; dispid 4;
property WindowName: WideString readonly dispid 5;
property Form: IDispatch readonly dispid 6;
end;
IWhiteboard = dispinterface // inherits from IChildForm
['{25B2DF1C-3683-4B13-8204-A0C37AF36164}']
property Kind: WindowKind readonly dispid 1;
property ID: Integer readonly dispid 2;
property Owner: IChildForm readonly dispid 3;
procedure Close; dispid 4;
property WindowName: WideString readonly dispid 5;
property Form: IDispatch readonly dispid 6;
end;
IDCCSession = dispinterface
['{20BCB67E-C1D0-4486-B6CE-4D01A8ABF44F}']
property Window: IChildForm readonly dispid 1;
end;
IServer = dispinterface // inherits from IOutputForm
['{2F8DFB47-DB99-40F7-B5A6-233BA930ED34}']
property ChannelCount: Integer readonly dispid 16;
property Channels[Index: Integer]: IChannel readonly dispid 17;
procedure SendLine(const Text: WideString); dispid 18;
property Hostname: WideString dispid 19;
property ServerName: WideString readonly dispid 20;
property Port: Integer readonly dispid 21;
procedure Connect; dispid 22;
procedure Disconnect; dispid 23;
property Interpreter: VSSprout readonly dispid 24;
property QueryCount: Integer readonly dispid 25;
property Queries[Index: Integer]: IQuery readonly dispid 26;
property Socket: ISockets readonly dispid 27;
procedure Clear(ClearHistory: WordBool); dispid 8;
property History: IStrings readonly dispid 9;
procedure RunCommand(const Command: WideString); dispid 10;
property Output: ITextScroller readonly dispid 11;
property Kind: WindowKind readonly dispid 1;
property ID: Integer readonly dispid 2;
property Owner: IChildForm readonly dispid 3;
procedure Close; dispid 4;
property WindowName: WideString readonly dispid 5;
property Form: IDispatch readonly dispid 6;
end;
IVSSprout = dispinterface
['{2CC78AC1-A944-11D1-B136-F9CE35176930}']
procedure SetVar(const Name: WideString; const Value: WideString); dispid 1;
procedure SetVarLocal(const Name: WideString; const Value: WideString); dispid 2;
function GetVar(const Name: WideString): WideString; dispid 3;
procedure Execute(const Command: WideString); dispid 4;
procedure ExecuteNoEval(const Command: WideString); dispid 5;
function Parse(const Text: WideString): WideString; dispid 6;
procedure IncVar(const Name: WideString; Amount: Integer); dispid 7;
property State: Integer readonly dispid 8;
function GetInterface(Num: Integer): IDispatch; dispid 9;
procedure MapInterface(Num: Integer; const Disp: IDispatch); dispid 10;
end;
ISockets = dispinterface
['{38980E25-C1AC-4CBE-954B-4E3AE482EFE4}']
property IPAddr: WideString dispid 1;
property Port: WideString dispid 2;
procedure SendText(const Text: WideString); dispid 3;
function ReadText: WideString; dispid 4;
procedure SendBuffer(Buffer: {??PSafeArray} OleVariant); dispid 5; // array of byte
function ReadBuffer(MaxLength: Integer; out Buffer: {??PSafeArray} OleVariant): Integer; dispid 6; // array of byte
procedure Connect; dispid 8;
procedure Close; dispid 9;
procedure Listen; dispid 10;
function ListenRange(Low: Integer; High: Integer): Integer; dispid 11;
procedure CancelListen; dispid 12;
function GetLocalIPAddr(Socket: Integer): WideString; dispid 13;
function GetPeerIPAddr(Socket: Integer): WideString; dispid 14;
function GetLocalPort(Socket: Integer): Integer; dispid 15;
function GetPeerPort(Socket: Integer): Integer; dispid 16;
function PeekText: WideString; dispid 17;
property SocketNumber: Integer dispid 19;
property MasterSocket: Integer dispid 21;
property State: SocketState readonly dispid 22;
property MaxSockets: Integer readonly dispid 23;
property UseSocks: WordBool dispid 24;
property SocksIPAddr: WideString dispid 25;
property SocksPort: WideString dispid 26;
property SocksUsername: WideString dispid 27;
property NonBlocking: WordBool dispid 28;
property Timeout: Integer dispid 29;
property MaximumReceiveLength: Integer dispid 30;
function Accept: Integer; dispid 31;
end;
ITextScroller = dispinterface
['{4E0C8BCD-7B42-42B9-8E4B-43A235C13D74}']
procedure AddFG(FG: Integer; const Text: WideString); dispid 1;
procedure AddFGBitmapFile(FG: Integer; const Bitmap: WideString; const Text: WideString); dispid 2;
procedure Clear; dispid 3;
procedure PageUp; dispid 4;
procedure PageDown; dispid 5;
function GetText: WideString; dispid 6;
procedure FlushBitmaps; dispid 7;
procedure FlushOneBitmap(const FileName: WideString); dispid 8;
property Background: Integer dispid 9;
property BufferSize: Integer dispid 10;
property FontName: WideString dispid 11;
property FontSize: Integer dispid 12;
property HyperlinkColor: Integer dispid 13;
property ScriptLinkColor: Integer dispid 14;
property TimeStamps: WordBool dispid 15;
property TimeStampFormat: WideString dispid 16;
property Logging: WordBool dispid 17;
end;
IChannel = dispinterface // inherits from IOutputForm
['{D8836D1E-E047-4614-8752-4D922C51DAE4}']
property Name: WideString readonly dispid 16;
property Mode: WideString readonly dispid 17;
property Topic: WideString readonly dispid 18;
property Key: WideString readonly dispid 19;
property Limit: Integer readonly dispid 20;
property TopicSetter: WideString readonly dispid 21;
property TopicTime: Integer readonly dispid 22;
property TopicHistory: IStrings readonly dispid 23;
procedure Clear(ClearHistory: WordBool); dispid 8;
property History: IStrings readonly dispid 9;
procedure RunCommand(const Command: WideString); dispid 10;
property Output: ITextScroller readonly dispid 11;
property Kind: WindowKind readonly dispid 1;
property ID: Integer readonly dispid 2;
property Owner: IChildForm readonly dispid 3;
procedure Close; dispid 4;
property WindowName: WideString readonly dispid 5;
property Form: IDispatch readonly dispid 6;
end;
// Constants for enum WindowKind
type
WindowKind = TOleEnum;
const
Server = $00000000;
CHANNEL = $00000001;
QUERY = $00000002;
DCCCHAT = $00000003;
WHITEBOARD = $00000004;
// Constants for enum SocketState
type
SocketState = TOleEnum;
const
sockDisconnected = $00000000;
sockDNS = $00000001;
sockConnecting = $00000002;
sockConnected = $00000003;
sockRequestedSocks = $00000004;